package com.luxk.db.block;

import com.luxk.db.block.BlockCacheHeader.BlockSize;
import com.luxk.db.block.BlockCacheHeader.BlockType;
import com.luxk.util.ByteArrayUtil;

public class BlockCacheHeaderHelper {
	
	/* format
	 * baseOffset + 0,  1 byte : block type
	 * baseOffset + 1,  1 byte : block size type
	 * baseOffset + 2,  4 byte : DBA
	 * baseOffset + 6,  8 byte : system change number
	 * baseOffset + 14, 1 byte : block change sequence
	 * baseOffset + 15, 1 byte : option flags
	 */
	private static final int OFFSET_BLOCK_TYPE = 0;
	private static final int OFFSET_BLOCK_SIZE = 1;
	private static final int OFFSET_DBA = 2;
	private static final int OFFSET_SCN = 6;
	private static final int OFFSET_SEQ = 14;
	private static final int OFFSET_FLAGS = 15;
	
	public static int getChecksum() {
		return 0;
	}
	
	public static BlockType getBlockType(byte[] buffer, int baseOffset) {
		return BlockType.get(buffer[baseOffset + OFFSET_BLOCK_TYPE]);
	}
	
	public static void setBlockType(byte[] buffer, int baseOffset,
			BlockType type) {
		buffer[baseOffset + OFFSET_BLOCK_TYPE] = (byte)type.getType();
	}
	
	public static BlockSize getSizeType(byte[] buffer, int baseOffset) {
		return BlockSize.get(buffer[baseOffset + OFFSET_BLOCK_SIZE]);
	}
	
	public static void setSizeType(byte[] buffer, int baseOffset,
			BlockSize size) {
		buffer[baseOffset + OFFSET_BLOCK_SIZE] = (byte)size.getSizeType();
	}

	public static int getDba(byte[] buffer, int baseOffset) throws Exception {
		return ByteArrayUtil.readInt(buffer, baseOffset + OFFSET_DBA);
	}	

	public static void setDba(byte[] buffer, int baseOffset, int dba) 
			throws Exception {
		ByteArrayUtil.writeInt(dba, buffer, baseOffset + OFFSET_DBA);
	}
	
	public static long getScn(byte[] buffer, int baseOffset) throws Exception {
		return ByteArrayUtil.readLong(buffer, baseOffset + OFFSET_SCN);
	}
	
	public static void setScn(byte[] buffer, int baseOffset, long scn) 
			throws Exception {
		ByteArrayUtil.writeLong(scn, buffer, baseOffset + OFFSET_SCN);
	}
	
	public static int getSeq(byte[] buffer, int baseOffset) {
		return (int)buffer[baseOffset + OFFSET_SEQ];
	}
	
	public static void setSeq(byte[] buffer, int baseOffset, int seq) 
			throws Exception {
		if(seq > Byte.MAX_VALUE)
			throw new Exception(
					"Maximum block change sequence exceeded(" + seq + ")");
		buffer[baseOffset + OFFSET_SEQ] = (byte)seq;
	}
	
	public static byte getFlags(byte[] buffer, int baseOffset) {
		return buffer[baseOffset + OFFSET_FLAGS];
	}
	
	public static void setFlags(byte[] buffer, int baseOffset, byte flags) {
		buffer[baseOffset + OFFSET_FLAGS] = flags;
	}
	
	public static int getCacheHeaderSize() {
		return OFFSET_FLAGS + 1;
	}
}
